---
description:
  Learn how to use client schemas to add a new field to an existing type in your schema using mock
  data, with Apollo Client and GraphQL queries.
---

# Mocking New Schema Capabilities

Imagine we're building out a new feature in our Space Explorer app — we'd like to display a
description of each rocket we can choose — but the backend support for this feature isn't going to
be available for another few weeks. In keeping with schema-first design, the team has decided that
we'll be adding a new field called `description` to an existing type in our schema called `Rocket`.

Even though this field doesn't exist in the schema yet, we can take advantage of client schemas to
document it as a client-side field. In this guide, we'll walk through a simple recipe for this
technique:

- declare client-side extensions to the schema using Apollo Client
- enhance client resolvers with mock data
- write GraphQL queries that leverage client-only types and fields

## 1. Extend Your Server Schema with a Client-Only Field

Before we can include this data in the UI, we'll need to define a client schema that extends our
server schema. We'll start by constructing an instance of ApolloClient with a few small additions.
Pass in `typeDefs` with extensions to the schema and `resolvers` which actually provide the mock
data:

```ts filename="app.config.ts"
import { provideApollo } from 'apollo-angular';
import { HttpLink } from 'apollo-angular/http';
import { inject } from '@angular/core';
import { InMemoryCache } from '@apollo/client';

const typeDefs = gql`
  extend type Rocket {
    description: String!
  }
`;

const resolvers = {
  Rocket: {
    description: () => 'A boilerplate standard space rocket',
  },
};

provideApollo(() => {
  const httpLink = inject(HttpLink);

  return {
    link: httpLink.create({ uri: '/graphql' }),
    cache: new InMemoryCache(),
    typeDefs,
    resolvers,
    // other options ...
  };
});
```

Documenting your client-side API in Schema Definition Language is incredibly valuable, as other
developers can easily see what client state is available in your app. Developers familiar with
GraphQL schemas should quickly be able to understand how to query for these fields in other places
throughout your app.

## 2. Introduce Richer Mock Data

Now that we have a basic resolver, we might find that during testing it's a bit boring to show the
same boilerplate text every time. In fact we might want to test different lengths of text to make
sure our layout still looks good. Introducing a mock data helper library such as
[faker.js](https://github.com/marak/Faker.js/) can help keep the mock data varied while testing. We
can incorporate it easily into this workflow:

```ts
import faker from 'faker/locale/en';

// returns either 1 or 2 latin sentences
const oneOrTwoSentences = () => faker.lorem.sentences(Math.random() < 0.5 ? 1 : 2);

const resolvers = {
  Rocket: {
    description: () => oneOrTwoSentences(),
  },
};
```

## 3. Query the Mocked Field with the `@client` Directive

Now, you’re ready to query your new field inside the `RocketDetails` component. Just add your new
field to the query and specify the `@client` directive, and start using it in your UI.

```ts
const GET_ROCKET_DETAILS = gql`
  query RocketDetails($rocketId: ID!) {
    rocket(id: $rocketId) {
      type
      description @client
    }
  }
`;

@Component({
  // ...
})
export class RocketDetailsComponent {
  @Input() rocketId: number;

  constructor(apollo: Apollo) {
    this.apollo.watchQuery({
      query: GET_ROCKET_DETAILS,
      variables: { rocketId },
    });
  }
}
```

## 4. Toggle on "Real" Data

Once the feature is ready on the backend, just remove the `@client` directive from your query. You
should now be able to see your real production data returned instead. It's probably a good idea to
clean up any unused client schema and resolvers at this time.
